package x.ovo.wechat.bot.core.http;

import x.ovo.wechat.bot.core.entity.BatchContactQuery;
import x.ovo.wechat.bot.core.entity.Contact;
import x.ovo.wechat.bot.core.entity.Member;
import x.ovo.wechat.bot.core.entity.Recommend;
import x.ovo.wechat.bot.core.http.result.SyncCheckResult;
import x.ovo.wechat.bot.core.http.result.UploadResult;
import x.ovo.wechat.bot.core.http.result.WebSyncResult;

import java.io.File;
import java.util.Collection;
import java.util.List;

/**
 * 微信 HTTP API 接口
 *
 * @author ovo, created by 2024/07/06
 */
public interface WechatApi {

    ///////////////// 登录、初始化 /////////////////

    /**
     * 获取 UUID
     *
     * @return {@link String } 微信服务器返回的的UUID
     */
    String getUUID();

    /**
     * 打印二维码
     * <p>
     * windows或mac os会打开图片显示二维码，linux环境输出二维码链接或终端输出二维码
     */
    void printQrCode(String uuid);

    /**
     * 登录，如果设置为自动登录，将尝试使用保存的凭证进行登录。
     *
     * @param autoLogin 是否尝试自动登录
     * @return 登录是否成功
     */
    boolean login(boolean autoLogin);

    /**
     * 推送登录，适用于登录掉线且保存的凭证失效（自动登录失败后），移动端会出现确认登录界面。
     *
     * @return uuid
     */
    String pushLogin();

    /**
     * 自动登录
     * <p>
     * 自动登录将使用保存在 config/login.json 的凭证进行登录。
     *
     * @return 自动登录结果
     */
    boolean autoLogin();

    /**
     * 检查登录是否成功，并获取登陆后的用户信息、session
     *
     * @param uuid UUID
     * @param tip  是否扫码登录，0-扫码，1-push
     * @return boolean
     */
    boolean checkLogin(String uuid, int tip);

    /**
     * 用户登出操作
     *
     * @return 登出是否成功
     */
    boolean logout();

    /**
     * 初始化微信，用于获取所需的各种资源和配置。
     *
     */
    void init();

    /**
     * 发送状态通知，主要用于向微信服务器同步消息已读取。
     *
     * @return 状态通知是否成功
     */
    boolean statusNotify(String id);

    ///////////////// 心跳、消息拉取 /////////////////

    /**
     * 执行同步检查。
     *
     * @return {@link SyncCheckResult} 同步检查的结果和相关信息。
     */
    SyncCheckResult syncCheck();

    /**
     * 消息拉取。
     *
     * @return {@link WebSyncResult} 拉取新消息返回的数据。
     */
    WebSyncResult webSync();

    ///////////////// 消息相关 /////////////////

    /**
     * 发送文本消息。
     *
     * @param to      接收消息的用户ID。
     * @param content 消息内容。
     * @return 发送是否成功。
     */
    boolean sendText(String to, String content);

    /**
     * 发送表情消息。
     *
     * @param to          接收消息的用户ID。
     * @param emoticonMd5 表情的MD5码。
     * @return 发送是否成功。
     */
    boolean sendEmoticon(String to, String emoticonMd5);

    /**
     * 发送图片消息。
     *
     * @param to   接收消息的用户ID。
     * @param file 图片文件。
     * @return 发送是否成功。
     */
    boolean sendImage(String to, File file);

    /**
     * 发送语音消息。
     *
     * @param to   接收消息的用户ID。
     * @param file 语音文件。
     * @return 发送是否成功。
     */
    boolean sendVoice(String to, File file);

    /**
     * 发送视频消息。
     *
     * @param to   接收消息的用户ID。
     * @param file 视频文件。
     * @return 发送是否成功。
     */
    boolean sendVideo(String to, File file);

    /**
     * 发送文件消息。
     *
     * @param to   接收消息的用户ID。
     * @param file 文件。
     * @return 发送是否成功。
     */
    boolean sendFile(String to, File file);

    /**
     * 上传媒体文件。
     *
     * @param to   接收消息的用户ID。
     * @param file 媒体文件。
     * @return {@link UploadResult} 上传结果。
     */
    UploadResult uploadMedia(String to, File file);

    /**
     * 下载图片。
     *
     * @param msgId 消息ID。
     * @return 图片的字节数据。
     */
    byte[] getImage(Long msgId);

    /**
     * 下载语音。
     *
     * @param msgId 媒体ID。
     * @return 语音的字节数据。
     */
    byte[] getVoice(Long msgId);

    /**
     * 下载视频。
     *
     * @param msgId 媒体ID。
     * @return 视频的字节数据。
     */
    byte[] getVideo(Long msgId);

    ///////////////// 联系人相关 /////////////////

    /**
     * 获取所有联系人。
     *
     * @return {@link List }<{@link Contact }> 联系人列表。
     */
    List<Contact> listContact();

    /**
     * 根据查询条件获取联系人。
     *
     * @param queries 查询条件集合。
     * @return {@link List }<{@link Contact }> 符合条件的联系人列表。
     */
    List<Contact> listContact(Collection<BatchContactQuery> queries);

    /**
     * 根据用户名获取联系人信息。
     *
     * @param username 联系人的用户名。
     * @return {@link Contact} 对应的联系人信息。
     */
    Contact getContact(String username);

    /**
     * 验证好友请求。
     *
     * @param recommend 好友请求信息。
     * @return 如果添加成功返回true，否则返回false。
     */
    boolean verifyUser(Recommend recommend);

    /**
     * 添加好友。
     *
     * @param username 好友的用户名。
     * @param content  添加好友时的留言内容。
     * @return 如果添加成功返回true，否则返回false。
     */
    boolean addFriend(String username, String content);

    /**
     * 修改联系人的备注信息。
     *
     * @param username 联系人的用户名。
     * @param remark   新的备注信息。
     * @return 如果修改成功返回true，否则返回false。
     */
    boolean modifyRemark(String username, String remark);

    /**
     * 创建群组。
     *
     * @param groupName 群组的名称。
     * @param members   群组的初始成员列表。
     * @return 如果群组创建成功返回true，否则返回false。
     */
    boolean creatGroup(String groupName, Collection<String> members);

    /**
     * 从群组中移除成员。
     *
     * @param groupName 群组的名称。
     * @param member    要移除的成员用户名。
     * @return 如果成员移除成功返回true，否则返回false。
     */
    boolean removeMember(String groupName, String member);

    /**
     * 邀请成员加入群组。
     *
     * @param groupName 群组的名称。
     * @param member    要邀请的成员用户名。
     * @return 如果邀请成功返回true，否则返回false。
     */
    boolean inviteMember(String groupName, String member);

    /**
     * 修改群组的名称。
     *
     * @param groupName 群组的当前名称。
     * @param newName   群组的新名称。
     * @return 如果群组名称修改成功返回true，否则返回false。
     */
    boolean modifyGroupName(String groupName, String newName);

    /**
     * 获取群组成员列表。
     *
     * @param groupName 群组的名称。
     * @return 群组的成员列表。
     */
    List<Member> listMember(String groupName);
}
